// iterators2.rs
// In this exercise, you'll learn some of the unique advantages that iterators
// can offer. Follow the steps to complete the exercise.
// Execute `rustlings hint iterators2` or use the `hint` watch subcommand for a hint.


// Step 1.
// Complete the `capitalize_first` function.
// "hello" -> "Hello"
pub fn capitalize_first(input: &str) -> String {
    let mut c = input.chars();
    match c.next() {
        None => String::new(),
        //此时c迭代器已经过去了第一个 first，当前迭代器指向剩下的字符
        
        Some(first) =>{
            let res = c.as_str();//剩下的迭代器收集起来做字符串
            format!("{}{}",first.to_uppercase().to_string(),res)//在拼接起来
        } ,
    }
}

// Step 2.
// Apply the `capitalize_first` function to a slice of string slices.
// Return a vector of strings.
// ["hello", "world"] -> ["Hello", "World"]
pub fn capitalize_words_vector(words: &[&str]) -> Vec<String> {
    //vec![]
    //words: &[&str]这个参数还恍惚了一下，仔细看就是引用参数，参数的内容是个切片，切片的元素是个 &str
    //words 直接有迭代器，迭代器 map 就是依次处理
    words.iter().map(|&word|capitalize_first(word)).collect()
}

// Step 3.
// Apply the `capitalize_first` function again to a slice of string slices.
// Return a single string.
// ["hello", " ", "world"] -> "Hello World"
pub fn capitalize_words_string(words: &[&str]) -> String {
    //String::new()
    
    //1.这里这个 mut 可以直接迭代器写么
    //  let mut strs = capitalize_words_vector(words);
    //  strs.join("")

     //2.collect 必须单独写一句去消费迭代器并且指定类型么？这两句可以变成一句么？
     //let x:Vec<_> = words.iter().map(|&word|capitalize_first(word)).collect();
     //x.join("")
     //2. 1 补充---上面好像可以，学会了collect 的完整写法，注意Vec<_>中间的下划线是因为这里 rust 可以推断
     words.iter().map(|&word|capitalize_first(word)).collect::<Vec<_>>().join("")
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_success() {
        assert_eq!(capitalize_first("hello"), "Hello");
    }

    #[test]
    fn test_empty() {
        assert_eq!(capitalize_first(""), "");
    }

    #[test]
    fn test_iterate_string_vec() {
        let words = vec!["hello", "world"];
        assert_eq!(capitalize_words_vector(&words), ["Hello", "World"]);
    }

    #[test]
    fn test_iterate_into_string() {
        let words = vec!["hello", " ", "world"];
        assert_eq!(capitalize_words_string(&words), "Hello World");
    }
}
